package com.mentaleye.util;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

import com.mentaleye.dal.model.SystemLogExample;

@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class SystemLogInterceptor implements Interceptor {

	public Object intercept(Invocation invocation) throws Throwable {
		MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
		Object parameter = invocation.getArgs()[1];

		// 获得boundSq
		BoundSql boundSql = mappedStatement.getBoundSql(parameter);
		String originalSql = boundSql.getSql().trim();
		Object parameterObject = boundSql.getParameterObject();

		// 获取用户编号
		// String handlerId = getHandlerId();
		String userId = "0000001";

		// 获取sql操作命令类型:insert/update/select/delete
		SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
		String commandType = sqlCommandType.name();

		// 获取传入的对应得参数
		if (parameterObject instanceof SystemLogExample) {
		} else {
			// 处理sql
			String finalSql = originalSql.toLowerCase();

			// 获取表名
			String tableName = getTableBySql(finalSql, commandType);

			// 获取字段
			String[] columns = getColumnsBySql(finalSql, commandType);

			// 插入数据
			insertLog(mappedStatement,tableName, userId, columns, commandType);
		}

		return invocation.proceed();
	}

	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	public void setProperties(Properties properties) {
	}

	
	public String getUserId() {
		String userId = null;
		Subject currentUser = SecurityUtils.getSubject();
		Session session = currentUser.getSession();
		userId = (String) session.getAttribute("accountId");
		return userId;
	}

	public String[] getColumnsBySql(String sql, String commandType) {
		int beginIndex = 0;
		int endIndex = 0;
		String[] fields = null;
		String value = null;
		if (commandType.equals("INSERT")) {
			beginIndex = sql.indexOf("(") + 1;
			endIndex = sql.indexOf(")");
			value = sql.substring(beginIndex, endIndex).trim();
			fields = value.split(",");
		} else if (commandType.equals("UPDATE")) {
			sql = sql.replace('=', ' ');
			sql = sql.replace('?', ' ');
			beginIndex = sql.indexOf("set") + "set".length();
			if (beginIndex == "set".length() - 1) {
				beginIndex = sql.indexOf("SET") + "SET".length();
			}
			endIndex = sql.indexOf("where");
			if (endIndex == -1) {
				endIndex = sql.indexOf("WHERE");
			}
			value = sql.substring(beginIndex, endIndex).trim();
			fields = value.split(",");
		} else if (commandType.equals("DELETE")) {
			sql = sql.replace('=', ' ');
			sql = sql.replace('?', ' ');
			beginIndex = sql.indexOf("where") + "where".length();
			if (beginIndex == "where".length() - 1) {
				beginIndex = sql.indexOf("WHERE") + "WHERE".length();
				;
			}
			value = sql.substring(beginIndex).trim();
			fields = value.split(",");
		}
		return fields;
	}

	public String getTableBySql(String sql, String commandType) {
		int beginIndex = 0;
		int endIndex = 0;
		if (commandType.equals("INSERT")) {
			beginIndex = sql.indexOf("into") + "into".length();
			if (beginIndex == "into".length() - 1) {
				beginIndex = sql.indexOf("INTO") + "INTO".length();
			}
			endIndex = sql.indexOf("(");
		} else if (commandType.equals("UPDATE")) {
			beginIndex = sql.indexOf("update") + "update".length();
			if (beginIndex == "update".length() - 1) {
				beginIndex = sql.indexOf("UPDATE") + "UPDATE".length();
			}
			endIndex = sql.indexOf("set");
			if (endIndex == -1) {
				endIndex = sql.indexOf("SET");
			}
		} else if (commandType.equals("DELETE")) {
			beginIndex = sql.indexOf("from") + "from".length();
			if (beginIndex == "FROM".length() - 1) {
				beginIndex = sql.indexOf("FROM") + "FROM".length();
			}
			endIndex = sql.indexOf("where");
			if (endIndex == -1) {
				endIndex = sql.indexOf("WHERE");
			}
		}
		return sql.substring(beginIndex, endIndex).trim();
	}

	public String getInsertLogSql(String tableName, String userId, String[] columns, String commandType) {
		// 获得时间
		Calendar calendar = Calendar.getInstance();
		Date dateTime = calendar.getTime();
		String submitDate = DateFormatter.format(dateTime);
		
		String operateType = null;
		if (commandType.equals("INSERT")) {
			operateType = "插入";
		} else if (commandType.equals("UPDATE")) {
			operateType = "修改";
		} else if (commandType.equals("DELETE")) {
			operateType = "删除";
		}

		StringBuilder sb=new StringBuilder("INSERT INTO system_log (user_id,operate_type,table_name,column_name,submit_date) VALUES");
		for(int i=0;i<columns.length;i++)
		{
			if(i<columns.length-1)
			{
				sb.append("('"+userId+"','"+operateType+"','"+tableName+"','"+columns[i]+"','"+submitDate+"'),");
			}
			else
			{
				sb.append("('"+userId+"','"+operateType+"','"+tableName+"','"+columns[i]+"','"+submitDate+"')");
			}
		}
		return sb.toString().trim();
	}
	
	@SuppressWarnings("null")
	public void insertLog(MappedStatement mappedStatement,String tableName, String userId, String[] columns, String commandType) 
			throws SQLException{
		String insertSql = getInsertLogSql(tableName, userId, columns, commandType);
		if (insertSql != null || !insertSql.isEmpty()) {
			Connection connection = mappedStatement.getConfiguration().getEnvironment().getDataSource()
					.getConnection();
			PreparedStatement ps = connection.prepareStatement(insertSql);
			ps.executeUpdate();
		}
	}	
}
